using System;
using System.Collections.Generic;
using System.Text;
using PSE.Hosting.Management.Common;
using System.IO;

namespace PSE.Hosting.Management.Console
{
    class AddAssemblyCommand : ICommand
    {
        // Available options for AddAssembly command
        private const string AddAssemblyPackageOption = "/package";
        //private const string AddAssemblyDomainOption = "/domain";
        //private const string AddAssemblyUserNameOption = "/userName";
        //private const string AddAssemblyPasswordOption = "/password";

        private bool ValidateArguments(string[] args, out string[] returnArgs, out bool silentMode)
        {
            returnArgs = null;
            silentMode = false;

            // Possible options
            string packageName = String.Empty; // Required option.
            string assemblyname = String.Empty;
            //string domain = String.Empty;
            //string userName = String.Empty;
            //string password = String.Empty;

            string codeBase = String.Empty; // Required

            // Verify if there is a silent mode option.
            // We need to search this option first, to not show any message if errors happens in options,
            // before this option happens.
            for (int i = 1; i < args.Length; i++)
            {
                if (args[i].Equals(Constants.SilentModeOption))
                {
                    silentMode = true;
                }
            }

            for (int i = 1; i < args.Length; i++)
            {
                string[] arg;
                if (args[i].StartsWith("/"))
                {
                    // If the argument starts with '/' then it is an option.

                    // If present bypass the silent option.
                    if (!args[i].Equals(Constants.SilentModeOption))
                    {
                        arg = args[i].Split(':');

                        switch (arg[0].Trim().ToLower())
                        {
                            case AddAssemblyPackageOption:
                                packageName = arg[1].ToUpper();
                                break;

                            //case AddAssemblyDomainOption:
                            //    domain = arg[1].ToUpper();
                            //    break;

                            //case AddAssemblyUserNameOption:
                            //    userName = arg[1].ToUpper();
                            //    break;

                            default:
                                if (!silentMode)
                                {
                                    Messages.InvalidOptionError(arg[0]);
                                }
                                return false;
                        }
                    }
                }
                else
                {
                    // It is not an option.
                    // Assume it is the Code Base.
                    if (String.IsNullOrEmpty(codeBase))
                    {
                        codeBase = args[i];
                    }
                    else
                    {
                        if (!silentMode)
                            Messages.WriteError("Invalid code base.");
                        return false;
                    }
                }
            }

            // Validations

            // The package is mandatory.
            if (String.IsNullOrEmpty(packageName))
            {
                Messages.NoPackageSpecifiedError();
                return false;
            }

            // The file name is mandatory and must exist.
            if (String.IsNullOrEmpty(codeBase))
            {
                Messages.NoFileSpecifiedError();
                return false;
            }

            if (!File.Exists(codeBase))
            {
                Messages.FileDoesNotExistsError();
                return false;
            }

            returnArgs = new string[] { packageName, assemblyname, /*domain, userName, password,*/ codeBase };

            return true;
        }

        #region ICommand Members

        public void Execute(string[] args)
        {
            string[] returnArgs;
            bool silentMode;

            if (ValidateArguments(args, out returnArgs, out silentMode))
            {
                string packageName = returnArgs[0];
                string assemblyname = returnArgs[1];
                //string domain = returnArgs[2];
                //string userName = returnArgs[3];
                //string password = returnArgs[4];
                string codeBase = returnArgs[2];

                try
                {
                    ServiceFactory.Instance.GetService().AddAssembly(Constants.ServerName, packageName, "", codeBase/*, domain, userName, password*/);
                }
                catch (ArgumentException ex)
                {
                    if (!silentMode)
                    {
                        Messages.InvalidArgumentError(ex.Message);
                    }
                    return;
                }
                catch (Exception ex)
                {
                    if (!silentMode)
                    {
                        Messages.WriteFailMessage(ex.Message);
                    }
                }
            }
        }

        #endregion
    }
}
